﻿#region Copyright Notice

// 
// 
//  
//  Copyright (c) 2009-2011 Anindya Chatterjee
//  
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//  
//      http://www.apache.org/licenses/LICENSE-2.0
//  
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// 
// 

#endregion

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Threading;
using System.Windows.Forms;

namespace AbstractClass.LiveUpdate
{
    public class UpdateEngine
    {
        public static void CheckForUpdates()
        {
            string path = Constants.ModulePath;

            string[] appModules = Directory.GetFiles(path, "*.update");

            if (appModules.Length == 0)
                return;

            foreach (string element in appModules)
            {
                try
                {
                    ApplicationDefinition appModule = XObjectSerializer<ApplicationDefinition>.ReadFile(element);
                    string updateUrl = appModule.UpdateUrl;
                    WebRequest request = WebRequest.Create(updateUrl);
                    request.Proxy = Proxy.GetSystemProxy();

                    WebResponse response = request.GetResponse();
                    var reader = new StreamReader(response.GetResponseStream());
                    string updateXml = reader.ReadToEnd();
                    reader.Close();

                    ApplicationUpdater updateDefs =
                        new XObjectSerializer<ApplicationUpdater>().Deserialize(updateXml);
                    UpdateDefinition latestUpdate = updateDefs.Updates[updateDefs.Updates.Count - 1];

                    var oldVersion = new Version(appModule.Version);
                    var newVersion = new Version(latestUpdate.Version);

                    if (!latestUpdate.Version.Equals(appModule.Suppress) && oldVersion.CompareTo(newVersion) < 0)
                    {
                        if (latestUpdate.ApplicationName.Equals("LiveUpdate"))
                        {
                            if (File.Exists("LiveUpdate.msi"))
                                File.Delete("LiveUpdate.msi");
                            string updateFilePath = DownloadUpdates(latestUpdate.DownloadUrl);
                            if (File.Exists(updateFilePath))
                            {
                                var procInfo = new ProcessStartInfo("msiexec.exe")
                                                   {
                                                       Arguments = string.Format("/i \"{0}\" /qn /l*v \"{1}\"",
                                                                                 updateFilePath,
                                                                                 Constants.AppPath +
                                                                                 "\\LiveUpdate.log"),
                                                       UseShellExecute = false
                                                   };
                                Process.Start(procInfo);
                                Application.Exit();
                            }
                        }
                        else
                        {
                            var udlg = new UpdateDialog
                                           {
                                               UpdateInfo = latestUpdate,
                                               ApplicationIcon = appModule.Icon
                                           };

                            if (udlg.ShowDialog() == DialogResult.OK)
                            {
                                if (udlg.SuppressNotification)
                                {
                                    appModule.Suppress = latestUpdate.Version;
                                    XObjectSerializer<ApplicationDefinition>.WriteFile(element, appModule);
                                    continue;
                                }
                                Process.Start(latestUpdate.DownloadUrl);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    const string file = "updateerror.log";
                    var log = new List<string>
                                  {
                                      DateTime.Now + " : An error occurred during update.",
                                      DateTime.Now + " : " + ex.Message
                                  };

                    if (ex.InnerException != null)
                        log.Add(DateTime.Now + " : " + ex.InnerException.Message);
                    log.Add(DateTime.Now + " : " + ex.StackTrace);
                    log.Add(DateTime.Now + " : Error log ends.");
                    log.Add(Environment.NewLine);
                    log.Add(Environment.NewLine);

                    File.WriteAllLines(file, log.ToArray());
                }
            }
        }

        internal static string DownloadUpdates(string url)
        {
            string updatePath = Constants.AppPath;
            string fileName = updatePath + "\\LiveUpdate.msi";
            var client = new WebClient {Proxy = WebRequest.DefaultWebProxy, UseDefaultCredentials = true};

            var thread = new Thread(() => client.DownloadFile(url, fileName));
            thread.Start();
            thread.Join();
            return fileName;
        }
    }
}